﻿using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;

namespace Jim.OA.Service;

public  class OAClientFactory : ISingleton
{
    // OA配置
    private readonly OAOptions _oaOptions;
    // 缓存
    private readonly IMemoryCache _memoryCache;

    public OAClientFactory(IOptions<OAOptions> oaOptions, IMemoryCache memoryCache)
    { 
        _oaOptions = oaOptions.Value;
        _memoryCache = memoryCache;
    }

    public OAWebServiceClient CreateWebServiceClient() 
    {
        var client = new OAWebServiceClient(_oaOptions.WebServiceUrl, _oaOptions.IP);
        return client;
    }

    public OARestClient CreateRestClient()
    {
        OARestClient client;
        // 缓存key
        var key = $"oa-{_oaOptions.AppKey}-restApi-token";
        OATokenCache tokenCache = _memoryCache.Get<OATokenCache>(key);
        
        if (tokenCache.isNotNull() &&  tokenCache.Token.IsNotNullOrEmpty())
        {
            client = new OARestClient(tokenCache.AppKey, tokenCache.BaseUrl,tokenCache.Cpk,tokenCache.Secret, tokenCache.Spk, tokenCache.Token)
            {
                IsDebug = _oaOptions.IsDebug
            };
        }
        else
        {
            client = new OARestClient(_oaOptions.AppKey, _oaOptions.BaseUrl)
            {
                IsDebug = _oaOptions.IsDebug
            };
            var loginRes = client.TryLoginAsync();
            loginRes.Wait();
            if (loginRes.Result)
            {
                tokenCache = new OATokenCache()
                {
                    AppKey = client.AppKey,
                    BaseUrl = client.ServerUrl,
                    Cpk = client.Cpk,
                    Secret = client.Secret,
                    Spk = client.Spk,
                    Token = client.Token
                };
                _memoryCache.Set(key, tokenCache, TimeSpan.FromSeconds(1800 - 120L));
            }
        }
        return client;
    }


    public OARestClient CreateSsoClient()
    {
        var client = new OARestClient(_oaOptions.SsoAppKey, _oaOptions.BaseUrl)
        {
            IsDebug = _oaOptions.IsDebug
        };
        return client;
    }
}
